package org.fujay.langchain4jserver.infrastructure.persistence.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.fujay.langchain4jserver.domain.knowledge.entity.File;
import org.fujay.langchain4jserver.domain.knowledge.repository.FileRepository;
import org.fujay.langchain4jserver.domain.knowledge.vo.FileId;
import org.fujay.langchain4jserver.domain.knowledge.vo.KnowledgeBaseId;
import org.fujay.langchain4jserver.infrastructure.persistence.assembler.KnowledgeAssembler;
import org.fujay.langchain4jserver.infrastructure.persistence.mybatis.entity.KnowledgeFilePo;
import org.fujay.langchain4jserver.infrastructure.persistence.mybatis.mapper.KnowledgeFileMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 文件仓储实现
 */
@Repository
@RequiredArgsConstructor
public class FileRepositoryImpl implements FileRepository {

    private final KnowledgeFileMapper fileMapper;

    @Override
    public Optional<File> findById(FileId id) {
        KnowledgeFilePo po = fileMapper.selectById(id.value());
        return Optional.ofNullable(po).map(KnowledgeAssembler::convertToDomain);
    }

    @Override
    public List<File> findByKnowledgeBaseId(KnowledgeBaseId knowledgeBaseId) {
        LambdaQueryWrapper<KnowledgeFilePo> queryWrapper =
                Wrappers.<KnowledgeFilePo>lambdaQuery()
                        .eq(KnowledgeFilePo::getKnowledgeBaseId, knowledgeBaseId.value());
        List<KnowledgeFilePo> pos = fileMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(pos)) {
            return Collections.emptyList();
        }
        return pos.stream().map(KnowledgeAssembler::convertToDomain).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(File file, KnowledgeBaseId knowledgeBaseId) {
        KnowledgeFilePo po = KnowledgeAssembler.convertToPO(file, knowledgeBaseId);
        if (fileMapper.selectById(po.getId()) == null) {
            fileMapper.insert(po);
        } else {
            fileMapper.updateById(po);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAll(List<File> files, KnowledgeBaseId knowledgeBaseId) {
        if (CollectionUtils.isEmpty(files)) {
            return;
        }
        // 简单的循环保存，可以优化为批量插入/更新
        for (File file : files) {
            save(file, knowledgeBaseId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(FileId id) {
        fileMapper.deleteById(id.value());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByKnowledgeBaseId(KnowledgeBaseId knowledgeBaseId) {
        LambdaQueryWrapper<KnowledgeFilePo> deleteWrapper =
                Wrappers.<KnowledgeFilePo>lambdaQuery()
                        .eq(KnowledgeFilePo::getKnowledgeBaseId, knowledgeBaseId.value());
        fileMapper.delete(deleteWrapper);
    }
}
